<template>
  <el-form ref="formRef" label-width="auto" label-position="right">
    <Border v-if="editorForm.border" />
    <Background v-if="editorForm.background" />
    <BorderBottom v-if="editorForm.borderBottom" />
    <BorderLeft v-if="editorForm.borderLeft" />
    <BorderRight v-if="editorForm.borderRight" />
    <BorderTop v-if="editorForm.borderTop" />
    <BorderRadius v-if="editorForm.borderRadius" />
    <Color v-if="editorForm.color" />
    <Opacity v-if="editorForm.opacity" />
    <FontSize v-if="editorForm.fontSize" />
    <FontStyle v-if="editorForm.fontWeight || editorForm.italic || editorForm.underline" />
    <FontFamily v-if="editorForm.fontFamily" />
    <Padding v-if="editorForm.padding" />
    <Margin v-if="editorForm.margin" />
    <Width v-if="editorForm.width" />
    <Height v-if="editorForm.height" />
    <Hover v-if="editorForm.hover" />
    <LineHeight v-if="editorForm.lineHeight" />
    <LineClamp v-if="editorForm.lineClamp" />
    <Content v-if="editorForm.content" />
    <Src v-if="editorForm.src" />
    <Link v-if="editorForm.link" />
    <Images v-if="editorForm.images" />
    <ContentOrigin v-if="editorForm.contentOrigin" />
    <CategoryOrigin v-if="editorForm.categoryOrigin" />
    <RichText v-if="editorForm.richText" />
    <Service v-if="editorForm.service" />
    <Swiper v-if="editorForm.swiper" />
    <Friend v-if="editorForm.friend" />
    <Delay v-if="editorForm.delay" />
    <Offset v-if="editorForm.offset" />
    <Aos v-if="editorForm.aos" />
    <Position v-if="editorForm.position" />
  </el-form>
</template>

<script setup>
import { computed, ref, provide, inject } from 'vue'
import { getTemplateDetail, updateTemplate } from '@/api/template'
import { useStore } from 'vuex'
import { myDebounce } from '@/utils/tools'
import { ElMessage, ElMessageBox } from 'element-plus'
import Background from './formItems/Background.vue'
import Border from './formItems/Border.vue'
import BorderBottom from './formItems/BorderBottom.vue'
import BorderLeft from './formItems/BorderLeft.vue'
import BorderRight from './formItems/BorderRight.vue'
import BorderTop from './formItems/BorderTop.vue'
import BorderRadius from './formItems/BorderRadius.vue'
import Color from './formItems/Color.vue'
import FontSize from './formItems/FontSize.vue'
import FontStyle from './formItems/FontStyle.vue'
import Padding from './formItems/Padding.vue'
import Margin from './formItems/Margin.vue'
import Width from './formItems/Width.vue'
import Height from './formItems/Height.vue'
import LineHeight from './formItems/LineHeight.vue'
import LineClamp from './formItems/LineClamp.vue'
import ContentOrigin from './formItems/ContentOrigin.vue'
import CategoryOrigin from './formItems/CategoryOrigin.vue'
import Swiper from './formItems/Swiper.vue'
import Friend from './formItems/Friend.vue'
import RichText from './formItems/RichText.vue'
import Service from './formItems/Service.vue'
import Aos from './formItems/Aos.vue'
import Delay from './formItems/Delay.vue'
import Offset from './formItems/Offset.vue'
import Link from './formItems/Link.vue'
import Src from './formItems/Src.vue'
import Content from './formItems/Content.vue'
import Hover from './formItems/Hover.vue'
import Opacity from './formItems/Opacity.vue'
import Position from './formItems/Position.vue'
import Images from './formItems/Images.vue'
import FontFamily from './formItems/FontFamily.vue'

const store = useStore()
const editorForm = computed(() => store.state.template.editorVariable)
const editorDom = computed(() => store.state.template.editorDom)
// 默认值
const defaultVariable = computed(() => store.state.template.editorVariableDefault)
const handleDefault = async key => {
  editorForm.value[key] = structuredClone(defaultVariable.value[key])
  editorForm.value[key].isDefault = true
}

// 恢复默认
const changeDefault = async field => {
  const isDefault = editorForm.value[field].isDefault
  if (isDefault) {
    handleDefault(field)
  }
}

// 获取组件内元素
const domList = ref([])
const getDom = () => {
  let elements = []
  // 如果当前的editorKey是复合属性，则证明是复合组件，需要获取子组件内的元素
  // 取editorKey的最后一个key，并从editorDom中找出data-props-key与之相等的元素，然后获取其所有绑定了_bind的元素作为domList
  if (store.state.template.editorKey.includes('.')) {
    const propsKey = store.state.template.editorKey.split('.')[0]
    const matchedElements = editorDom.value.querySelectorAll(`[data-props-key="${propsKey}"]`)
    matchedElements.forEach(el => {
      elements.push(
        ...(el.getAttribute('_bind') ? [el] : []),
        ...el.querySelectorAll('[_bind]')
      )
    })
  } else {
    elements.push(
      ...(editorDom.value.getAttribute('_bind') ? [editorDom.value] : []),
      ...editorDom.value.querySelectorAll('[_bind]')
    )
  }
  domList.value = elements
}
getDom()

// 组件全局属性更新(更新组件的默认配置)
const updateGlobalProp = myDebounce(async (globalId, prop) => {
  try {
    const res1 = await getTemplateDetail({ id: globalId })
    if (res1.code === 20000) {
      const { editorKey } = store.state.template
      if (editorKey.includes('.')) {
        // 分割后取最后一个key
        const key = editorKey.split('.').pop()
        res1.data.properties[key] = { ...res1.data.properties[key], ...prop }
      } else {
        res1.data.properties[editorKey] = { ...res1.data.properties[editorKey], ...prop }
      }
      res1.data.properties = JSON.stringify(res1.data.properties)
      const res2 = await updateTemplate(res1.data)
      if (res2.code === 20000) {
        backUpdate()
        // 找到其它引用了该全局组件的组件
        const {categoryVariable, componentList, componentId} = store.state.template
        const others = componentList.filter(item => item.importIds && item.importIds.includes(globalId) && item.id !== componentId)
        if (others.length > 0) {
          const names = others.map(item => item.name).join('、')
          ElMessageBox.confirm(
            `更新成功！检测到当前页面组件${names}均使用了该设置，是否立即同步更新？`,
            '提示',
            {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'success',
            }
          )
            .then(async () => {
              for (const item of others) {
                await updateComponent(item.id, item.componentKey, categoryVariable[item.componentKey])
              }
            })
            .catch(() => {
              ElMessage.info('已取消，同步效果请保存后手动刷新页面查看！')
            })
        }
      }
    }
  } catch {
    ElMessage.error('更新失败')
  }
}, 500)

// 后端更新
const { updateComponent } = inject('design')
const backUpdate = myDebounce(() => {
  const {componentId, componentKey, componentVariable } = store.state.template
  updateComponent(componentId, componentKey, componentVariable)
}, 500)

provide('commonForm', {
  editorForm,
  domList,
  changeDefault,
  backUpdate,
  updateGlobalProp
})
</script>

<style lang="scss">
.el-radio-group .el-radio {
  margin-right: 8px;
}

// 图片上传样式
.form-img {
  height: 100px;
  width: 150px;
  border: 1px dashed $borderColor;
  cursor: pointer;
  display: flex;
  justify-content: center;
  align-items: center;

  .has-img {
    height: 100%;
    width: 100%;
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;

    img {
      max-width: 100%;
      max-height: 100%;
    }

    span {
      display: none;
      position: absolute;
      right: 0;
      top: 0;
      background-color: $failColor;
      height: 20px;
      width: 20px;
      font-size: 18px;
      color: #fff;
    }

    &:hover {
      span {
        display: flex;
        align-items: center;
        justify-content: center;
      }
    }
  }
}

// 内外边距设置
.padding-setting {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-gap: 10px;

  .padding-item {
    display: flex;
    align-items: center;
    padding-left: 15px;
    min-width: 0;
    font-size: 12px;
    color: #606266;

    span {
      flex-shrink: 0;
    }

    .el-input {
      // margin-left: 12px;
      margin-left: 0px;
    }
  }

  .padding-item.p0 {
    padding-left: 0;
  }
}

// 自定义下一行
.custom-next {
  width: 100%;

  .el-form-item:not(:first-child) {
    margin-top: 15px;
  }
}

// 自定义行内块
.custom-after {
  display: inline-block;
  margin-left: 5px;

  .el-input {
    width: 90px;
    box-sizing: border-box;
  }
  i {
    margin-left: 10px;
    font-size: 14px;
    color: $mainColor;
    cursor: pointer;
  }
}

.pl-28 {
  margin-top: 15px;
  font-size: 12px;
  color: #606266;
}
</style>